package ar.uba.fi.taller2.ftrs.tree;

import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import ar.uba.fi.taller2.ftrs.common.Parameters;
import ar.uba.fi.taller2.ftrs.tree.BSTree.Entry;

public class FileManager {
		
	// el wd por defecto es un directorio llamado ftrs debajo del 
	// directorio actual de la aplicacion
	private static final String DEFAULT_WD = new String("."+File.separator+"ftrs"+File.separator);
	
	private static String WorkingDirectory;
	
	/// Metodos privados ///
	
	public static void iniciate() {

		WorkingDirectory = null;
		// obtengo del archivo de configuracion el directorio de trabajo de la aplicacion
		WorkingDirectory = Parameters.getParametros().getMessage("WORKING_DIRECTORY", 1);
		if (WorkingDirectory==null || WorkingDirectory.length()==0) {
			WorkingDirectory = DEFAULT_WD;
		}
		if (!WorkingDirectory.endsWith(File.separator)) {
			WorkingDirectory += File.separator;
		}
	}

	   public static  void write(BSLeafNode nodo)
	   {
		   iniciate();
		  
		   ObjectOutputStream outputStream = null;
		   try{
		       //Construct the LineNumberReader object
		      outputStream = new ObjectOutputStream(new FileOutputStream(WorkingDirectory+"tree"+File.separator+nodo.getId()+".dat"));
		      outputStream.writeObject(nodo);
		      
		   } catch (FileNotFoundException ex) {
			   ex.printStackTrace();
	       } catch (IOException ex) {
	           ex.printStackTrace();
	       } finally {
	           //Close the ObjectOutputStream
	           try {
	               if (outputStream != null) {
	                   outputStream.flush();
	                   outputStream.close();
	               }
	           } catch (IOException ex) {
	               ex.printStackTrace();
	           }
	       }
   
	   }
	   
	   
	   public static  BSLeafNode readBSLeafNode(String hashCode)
	   {
		   iniciate();
		   if (hashCode==null) hashCode="";
		   ObjectInputStream inputStream = null;
		   BSLeafNode node=null;
		   try{
		       //Construct the LineNumberReader object
			   
			   inputStream = new ObjectInputStream(new FileInputStream(WorkingDirectory+"tree"+File.separator+hashCode+".dat"));
			   node=(BSLeafNode) inputStream.readObject();
		      		      
		   } catch (EOFException ex) { //This exception will be caught when EOF is reached
	            System.out.println("End of file reached.");
	        } catch (ClassNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (FileNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (IOException ex) {
	            ex.printStackTrace();
	        } finally {
	            //Close the ObjectInputStream
	            try {
	                if (inputStream != null) {
	                    inputStream.close();
	                }
	            } catch (IOException ex) {
	                ex.printStackTrace();
	            }
	            
	        }
	        return node;
	   }
	   
	   
	   
	   
	   
	   public static  void write(BSGuideNode nodo)
	   {
		   iniciate();
		   ObjectOutputStream outputStream = null;
		   try{
		       //Construct the LineNumberReader object
		      outputStream = new ObjectOutputStream(new FileOutputStream(WorkingDirectory+"tree"+File.separator+nodo.getId()+".dat"));
		      outputStream.writeObject(nodo);
		      
		   } catch (FileNotFoundException ex) {
			   ex.printStackTrace();
	       } catch (IOException ex) {
	           ex.printStackTrace();
	       } finally {
	           //Close the ObjectOutputStream
	           try {
	               if (outputStream != null) {
	                   outputStream.flush();
	                   outputStream.close();
	               }
	           } catch (IOException ex) {
	               ex.printStackTrace();
	           }
	       }
   
	   }
	   
	   
	   public static  BSGuideNode readBSGuideNode(String hashCode)
	   {
		   iniciate();
		   ObjectInputStream inputStream = null;
		   BSGuideNode node=null;
		   try{
		       //Construct the LineNumberReader object
			   
			   inputStream = new ObjectInputStream(new FileInputStream(WorkingDirectory+"tree"+File.separator+hashCode+".dat"));
			   node=(BSGuideNode) inputStream.readObject();
		      		      
		   } catch (EOFException ex) { //This exception will be caught when EOF is reached
	            System.out.println("End of file reached.");
	        } catch (ClassNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (FileNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (IOException ex) {
	            ex.printStackTrace();
	        } finally {
	            //Close the ObjectInputStream
	            try {
	                if (inputStream != null) {
	                    inputStream.close();
	                }
	            } catch (IOException ex) {
	                ex.printStackTrace();
	            }
	            
	        }
	        return node;
	   }
	   
	   
	   
	   
	   public static  void write(Entry nodo)
	   {
		   iniciate();
		   ObjectOutputStream outputStream = null;
		   try{
		       //Construct the LineNumberReader object
		      outputStream = new ObjectOutputStream(new FileOutputStream(WorkingDirectory+"tree"+File.separator+"Entry_"+nodo.getId()+".dat"));
		      outputStream.writeObject(nodo);
		      
		   } catch (FileNotFoundException ex) {
			   ex.printStackTrace();
	       } catch (IOException ex) {
	           ex.printStackTrace();
	       } finally {
	           //Close the ObjectOutputStream
	           try {
	               if (outputStream != null) {
	                   outputStream.flush();
	                   outputStream.close();
	               }
	           } catch (IOException ex) {
	               ex.printStackTrace();
	           }
	       }
   
	   }
	   
	   
	   public static  Entry readEntry(String hashCode)
	   {
		   iniciate();
		   ObjectInputStream inputStream = null;
		   Entry node=null;
		   if (hashCode==null) hashCode="";
		   try{
		       //Construct the LineNumberReader object
			   
			   inputStream = new ObjectInputStream(new FileInputStream(WorkingDirectory+"tree"+File.separator+"Entry_"+hashCode+".dat"));
			   node=(Entry) inputStream.readObject();
		      		      
		   } catch (EOFException ex) { //This exception will be caught when EOF is reached
	            System.out.println("End of file reached.");
	        } catch (ClassNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (FileNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (IOException ex) {
	            ex.printStackTrace();
	        } finally {
	            //Close the ObjectInputStream
	            try {
	                if (inputStream != null) {
	                    inputStream.close();
	                }
	            } catch (IOException ex) {
	                ex.printStackTrace();
	            }
	            
	        }
	        return node;
	   }
	   
	   
	   public static  void write(BSTree nodo)
	   {
		   iniciate();
		   ObjectOutputStream outputStream = null;
		   try{
		       //Construct the LineNumberReader object
		      outputStream = new ObjectOutputStream(new FileOutputStream(WorkingDirectory+"tree"+File.separator+"BSTree.dat"));
		      outputStream.writeObject(nodo);
		      
		   } catch (FileNotFoundException ex) {
			   ex.printStackTrace();
	       } catch (IOException ex) {
	           ex.printStackTrace();
	       } finally {
	           //Close the ObjectOutputStream
	           try {
	               if (outputStream != null) {
	                   outputStream.flush();
	                   outputStream.close();
	               }
	           } catch (IOException ex) {
	               ex.printStackTrace();
	           }
	       }
   
	   }
	   
	   
	  
	   public static  BSTree readBSTree()
	   {
		   iniciate();
		   ObjectInputStream inputStream = null;
		   BSTree node=null;
		   try{
		       //Construct the LineNumberReader object
			   
			   inputStream = new ObjectInputStream(new FileInputStream(WorkingDirectory+"tree"+File.separator+"BSTree.dat"));
			   node=(BSTree) inputStream.readObject();
		      		      
		   } catch (EOFException ex) { //This exception will be caught when EOF is reached
	            System.out.println("End of file reached.");
	        } catch (ClassNotFoundException ex) {
	            ex.printStackTrace();
	        } catch (FileNotFoundException ex) {
	        	System.out.println("el archivo BSTree.dat no se encontro por lo q se creara un nuevo archivo");
	        } catch (IOException ex) {
	            ex.printStackTrace();
	        } finally {
	            //Close the ObjectInputStream
	            try {
	                if (inputStream != null) {
	                    inputStream.close();
	                }
	            } catch (IOException ex) {
	                ex.printStackTrace();
	            }
	            
	        }
	        return node;
	   }
	 
	   public static  void delete(Entry entry){
		   iniciate();
	   	   String fileName = WorkingDirectory+"tree"+File.separator+"Entry_"+entry.getId()+".dat";
			    // A File object to represent the filename
			    File f = new File(fileName);

			    // Make sure the file or directory exists and isn't write protected
			    if (!f.exists())
			      throw new IllegalArgumentException(
			          "Delete: no such file or directory: " + fileName);

			    if (!f.canWrite())
			      throw new IllegalArgumentException("Delete: write protected: "
			          + fileName);

			    // If it is a directory, make sure it is empty
			    if (f.isDirectory()) {
			      String[] files = f.list();
			      if (files.length > 0)
			        throw new IllegalArgumentException(
			            "Delete: directory not empty: " + fileName);
			    }

			    // Attempt to delete it
			    boolean success = f.delete();

			    if (!success)
			      throw new IllegalArgumentException("Delete: deletion failed");
			  }

	public static BSNode readBSNode(String string) {
		if (string.contains("BSLeafNode" ))
				return readBSLeafNode(string);
		if (string.contains("BSGuideNode" ))
			return readBSGuideNode(string);
		return null;
	}
	public static void write(BSNode node) {
		if (node.getId().contains("BSLeafNode" ))
				 write((BSLeafNode)node);
		if (node.getId().contains("BSGuideNode" ))
			write((BSGuideNode)node);

	}

}
